package com.erlin.store.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.erlin.common.exception.ElException;
import com.erlin.common.utils.JwtTokenUtils;
import com.erlin.common.utils.MessageUtils;
import com.erlin.store.constant.StoreConfigConstant;
import com.erlin.store.controller.param.StoreDistanceConfigParam;
import com.erlin.store.entity.Store;
import com.erlin.store.entity.StoreDeliveryConfig;
import com.erlin.store.mapper.StoreDeliveryConfigMapper;
import com.erlin.store.service.IStoreDeliveryConfigService;
import com.erlin.store.service.IStoreService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author alin
 * @since 2021-05-25
 */
@Service
public class StoreDeliveryConfigServiceImpl extends ServiceImpl<StoreDeliveryConfigMapper, StoreDeliveryConfig> implements IStoreDeliveryConfigService {
    @Autowired
    private IStoreService storeService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean diliveryConfig(StoreDistanceConfigParam param) {
        //数据校验
        //TODO 校验当前用户是否对此店铺有操作权限 更改为成员可以操作。
        Store store = Optional.ofNullable(storeService.getOne(Wrappers.<Store>lambdaQuery().eq(Store::getMid, param.getStoreMid()))).orElseThrow(() -> new ElException(MessageUtils.getMessage("store.not.exist")));
        long userId = JwtTokenUtils.getCurrentUserId();
        if (!Objects.equals(userId, store.getDirectorId())) {
            log.error("商户非法配置操作！请检查[userId:" + userId + "],[商户mid" + param.getStoreMid() + "]");
            throw new ElException(MessageUtils.getMessage("store.not.has.operation.auth"));
        }
        checkUserAndConfig(param);
        //更新配置
        List<StoreDeliveryConfig> entitys = param.getConfigs().stream().map(config -> {
            StoreDeliveryConfig target = new StoreDeliveryConfig();
            BeanUtils.copyProperties(config, target);
            target.setStoreId(store.getId());
            return target;
        }).collect(Collectors.toList());
        saveBatch(entitys);
        return true;
    }

    private void checkUserAndConfig(StoreDistanceConfigParam param) {
        //校验配置
        for (StoreDistanceConfigParam.config config : param.getConfigs()
        ) {
            if (BigDecimal.ZERO.compareTo(config.getPrice()) > 0) {
                throw new ElException(MessageUtils.getMessage("store.config.price.error"));
            }
            if (BigDecimal.ZERO.compareTo(config.getReductionAmout()) > 0) {
                throw new ElException(MessageUtils.getMessage("store.config.reductionamout.error"));
            }
            if (BigDecimal.ZERO.compareTo(config.getReducePrice()) > 0) {
                throw new ElException(MessageUtils.getMessage("store.config.reduceprice.error"));
            }
            //如果有满减 就必须有满减后价格
            if (Objects.nonNull(config.getReductionAmout()) && Objects.isNull(config.getReducePrice())) {
                throw new ElException(MessageUtils.getMessage("store.config.reduce.error"));
            }
            if (Objects.nonNull(config.getReducePrice()) && Objects.isNull(config.getReductionAmout())) {
                throw new ElException(MessageUtils.getMessage("store.config.reduce.error"));
            }
            if (Objects.nonNull(config.getReducePrice()) && config.getPrice().compareTo(config.getReducePrice()) < 0) {
                throw new ElException(MessageUtils.getMessage("store.config.reduce.price.toohigh"));
            }
            switch (config.getDistanceType()) {
                case StoreConfigConstant.DISTANCE_LTO: {
                    if (BigDecimal.TEN.compareTo(config.getPrice()) < 0) {
                        throw new ElException(MessageUtils.getMessage("store.config.lto.price.toohigh"));
                    }
                    if (config.getDeliveryTime() > 60) {
                        throw new ElException(MessageUtils.getMessage("store.config.lto.deliverytime.toolong"));
                    }
                }
            }

        }

    }
}
